use salvo::prelude::*;
use serde::Serialize;

#[derive(Debug, Serialize)]
pub struct ApiResponse<T: Serialize> {
    pub code: i32,
    pub message: String,
    pub data: Option<T>,
}

impl<T: Serialize> ApiResponse<T> {
    pub fn new(code: i32, message: impl Into<String>, data: Option<T>) -> Self {
        Self {
            code,
            message: message.into(),
            data,
        }
    }
    #[allow(dead_code)]
    pub fn success(data: T) -> Self {
        Self::new(200, "success", Some(data))
    }

    pub fn error(code: i32, message: impl Into<String>) -> Self {
        Self::new(code, message, None)
    }
}

use salvo::http::ResBody;

impl<T: Serialize> Into<Response> for ApiResponse<T> {
    fn into(self) -> Response {
        let mut res = Response::new();
        res.status_code(StatusCode::OK);
        let json_str = serde_json::to_string(&self).unwrap();
        res.body(ResBody::Once(json_str.into_bytes().into()));
        res
    }
}
